﻿using System;
using System.Collections.Generic;
using System.Xml;
using Autodesk.Revit.DB;
using YArchitech.Revit.RevitExtension;
using HYOpeningCommon.OpeningEX;
using HYOpeningCommon.OpeningProfile;
using HYOpeningCommon.Public;

namespace HYOpeningCommon.DbOpening
{
	public class DbRectBeamOpening : DbNativeOpening
	{
		private static Transform getBeamTransform(XYZ origin, FamilyInstance beam)
		{
			Transform identity = Transform.Identity;
			Line line = (beam.Location as LocationCurve).Curve as Line;
			if (line == null)
			{
				return identity;
			}
			identity.Origin = origin;
			identity.BasisX = (line.GetEndPoint(1) - line.GetEndPoint(0)).Normalize();
			identity.BasisY = XYZ.BasisZ.Normalize();
			identity.BasisZ = identity.BasisX.CrossProduct(identity.BasisY);
			return identity;
		}

		public override bool CreateOpeningFamilyInstance(ViewScene ViewScene, out Element elem3D, out Element elem2D)
		{
			elem2D = null;
			Autodesk.Revit.DB.View viewOpening2D = ViewScene.m_viewOpening2D;
			if (viewOpening2D == null)
			{
				elem3D = null;
				return false;
			}
			Document document = viewOpening2D.Document;
			OpeningXData openingXData = new OpeningXData();
			base.GetOpeningXDataBase(ref openingXData);
			Transaction transaction = new Transaction(document, "CreateOpeningFamilyInstance");
			try
			{
				transaction.Start();
				Element element = document.GetElement(this.m_strHostUniqueId);
				FamilyInstance beam = element as FamilyInstance;
				OpeningProfileRect openingProfileRect = this.m_profile as OpeningProfileRect;
				double num = openingProfileRect.m_cutWidth / 2.0 + openingProfileRect.m_dExtendDist;
				double num2 = openingProfileRect.m_cutWidth / 2.0 + openingProfileRect.m_dExtendDist;
				double num3 = openingProfileRect.m_cutHeight / 2.0 + openingProfileRect.m_dExtendDist;
				double num4 = openingProfileRect.m_cutHeight / 2.0 + openingProfileRect.m_dExtendDist;
				Transform beamTransform = DbRectBeamOpening.getBeamTransform(openingProfileRect.m_position, beam);
				XYZ xyz = beamTransform.OfPoint(new XYZ(num, num4, 0.0));
				XYZ xyz2 = beamTransform.OfPoint(new XYZ(num, -num3, 0.0));
				XYZ xyz3 = beamTransform.OfPoint(new XYZ(-num2, -num3, 0.0));
				XYZ xyz4 = beamTransform.OfPoint(new XYZ(-num2, num4, 0.0));
				Line line = YJKLineEx.YJKGetBound(xyz, xyz2);
				Line line2 = YJKLineEx.YJKGetBound(xyz2, xyz3);
				Line line3 = YJKLineEx.YJKGetBound(xyz3, xyz4);
				Line line4 = YJKLineEx.YJKGetBound(xyz4, xyz);
				CurveArray curveArray = new CurveArray();
				curveArray.Append(line);
				curveArray.Append(line2);
				curveArray.Append(line3);
				curveArray.Append(line4);
				Opening opening = document.Create.NewOpening(element, curveArray, (Autodesk.Revit.Creation.eRefFace)4);
				openingXData.m_dHeight = xyz.DistanceTo(xyz2);
				openingXData.m_dWidth = xyz.DistanceTo(xyz4);
				openingXData.m_eOpeningProfile = 1;
				openingXData.WriteOpeningXData(opening);
				transaction.Commit();
				elem3D = opening;
			}
			catch (Exception)
			{
				elem3D = null;
				transaction.RollBack();
				return false;
			}
			return true;
		}

		public override bool CreateOpeningPreviewInstance(out Element elemPreview, PreViewScene preViewScene)
		{
			OpeningProfileRect openingProfileRect = this.m_profile as OpeningProfileRect;
			XYZ position = openingProfileRect.m_position;
			XYZ directionProfile = openingProfileRect.m_directionProfile;
			XYZ xyz = XYZ.BasisZ.CrossProduct(directionProfile);
			Transaction transaction = new Transaction(preViewScene.m_doc, "CreateModelGroup");
			bool result;
			try
			{
				XYZ xyz2 = position + directionProfile * (this.m_dHostWidth / 2.0 + preViewScene.m_offset) + XYZ.BasisZ.Negate() * (openingProfileRect.m_cutHeight / 2.0);
				XYZ xyz3 = xyz2 + (openingProfileRect.m_dExtendDist + openingProfileRect.m_cutWidth / 2.0) * xyz;
				XYZ xyz4 = xyz2 + (openingProfileRect.m_dExtendDist + openingProfileRect.m_cutWidth / 2.0) * xyz.Negate();
				XYZ item = xyz4 + (openingProfileRect.m_dExtendDist * 2.0 + openingProfileRect.m_cutHeight) * XYZ.BasisZ;
				XYZ item2 = xyz3 + (openingProfileRect.m_dExtendDist * 2.0 + openingProfileRect.m_cutHeight) * XYZ.BasisZ;
				List<ElementId> list = new List<ElementId>();
				List<XYZ> list2 = new List<XYZ>();
				list2.Add(xyz3);
				list2.Add(xyz4);
				list2.Add(item);
				list2.Add(item2);
				SketchPlane sketchPlane = null;
				if (!CommonInterface.CreateSketchPlane(preViewScene.m_doc, openingProfileRect.m_directionProfile, xyz3, ref sketchPlane) || sketchPlane == null)
				{
					elemPreview = null;
					result = false;
				}
				else if (!CommonInterface.CreateModelLine(list2, preViewScene.m_doc, sketchPlane, ref list, preViewScene.m_modelLineElemId))
				{
					elemPreview = null;
					result = false;
				}
				else
				{
					XYZ xyz5 = position + directionProfile.Negate() * (this.m_dHostWidth / 2.0 + preViewScene.m_offset) + XYZ.BasisZ.Negate() * (openingProfileRect.m_cutHeight / 2.0);
					XYZ xyz6 = xyz5 + (openingProfileRect.m_dExtendDist + openingProfileRect.m_cutWidth / 2.0) * xyz;
					XYZ xyz7 = xyz5 + (openingProfileRect.m_dExtendDist + openingProfileRect.m_cutWidth / 2.0) * xyz.Negate();
					XYZ item3 = xyz7 + (openingProfileRect.m_dExtendDist * 2.0 + openingProfileRect.m_cutHeight) * XYZ.BasisZ;
					XYZ item4 = xyz6 + (openingProfileRect.m_dExtendDist * 2.0 + openingProfileRect.m_cutHeight) * XYZ.BasisZ;
					list2.Clear();
					list2.Add(xyz6);
					list2.Add(xyz7);
					list2.Add(item3);
					list2.Add(item4);
					sketchPlane = null;
					if (!CommonInterface.CreateSketchPlane(preViewScene.m_doc, openingProfileRect.m_directionProfile, xyz6, ref sketchPlane))
					{
						elemPreview = null;
						result = false;
					}
					else if (!CommonInterface.CreateModelLine(list2, preViewScene.m_doc, sketchPlane, ref list, preViewScene.m_modelLineElemId))
					{
						elemPreview = null;
						result = false;
					}
					else
					{
						transaction.Start();
						elemPreview = preViewScene.m_doc.Create.NewGroup(list);
						transaction.Commit();
						result = true;
					}
				}
			}
			catch (Exception)
			{
				transaction.RollBack();
				elemPreview = null;
				result = false;
			}
			return result;
		}

		public override bool IsNeedCreateFamily()
		{
			return false;
		}

		public override bool Equals(object obj)
		{
			return base.Equals(obj);
		}

		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		public override void AddSharedParameters(Element elem)
		{
		}

		public override bool Export2XmlNode(XmlElement xmlNode)
		{
			bool result;
			try
			{
				if (!base.Export2XmlNode(xmlNode))
				{
					result = false;
				}
				else
				{
					result = true;
				}
			}
			catch
			{
				xmlNode = null;
				result = false;
			}
			return result;
		}

		public override bool ImportByXmlNode(XmlNode xmlNode)
		{
			try
			{
				if (!base.ImportByXmlNode(xmlNode))
				{
					return false;
				}
			}
			catch
			{
				return false;
			}
			return true;
		}
	}
}
